package com.happyma.bbn;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.media.AudioManager;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.preference.PreferenceManager;

import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.material.navigation.NavigationView;
import com.happyma.bbn.player.PlayerService;
import com.happyma.bbn.utils.AsyncJSONURLsParser;
import com.happyma.bbn.utils.Common;
import com.happyma.bbn.utils.ContextGeeter;
import com.happyma.bbn.utils.RefreshApp;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Locale;

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{

    private static final int LANGUAGE_SETUP_CODE = 1000;
    private static final int LANGUAGE_RESULT_CODE = 1001;
    private static final int PROGRESS_INDEX = 1100;
    private static final int VOLUME_CHANGED = 1101;
    private DefaultBandwidthMeter bandwidthMeter =
            new DefaultBandwidthMeter.Builder(getApplication()).build();
    private DataSource.Factory dataSourecFactory;
    private DefaultTrackSelector trackSelector;
    private SimpleExoPlayer player;
    private HlsMediaSource hlsMediaSource;
    private PlayerView pv_view;
    private ImageButton playButton;
    private AudioManager mgr = null;
    private SeekBar music;
    private ImageButton speaker;
    private BroadcastReceiver updateUIReceiver;
    private BroadcastReceiver updateVolumeSeekbar;

    private PlayerService playerServiceIntent;
    private Intent psIntent;

    private DrawerLayout drawerLayout;
    private NavigationView navigationView;

    public boolean mBounded;
    public Toolbar toolbar;
    private WifiManager.WifiLock wifiLock;
    private PowerManager.WakeLock wakeLock;
    private SharedPreferences sharedPreferences;
    private PowerManager powerManager;
    private String packageName;
    private String assets;
    private static final String TAG = "MainActivity-->";

    ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBounded = true;
            PlayerService.LocalBinder localBinder = (PlayerService.LocalBinder) service;
            playerServiceIntent = localBinder.getServerInstance();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            unbindService(mConnection);
            mBounded = false;
            playerServiceIntent = null;
        }
    };

    Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            if (msg.what == VOLUME_CHANGED){
                music.setProgress(mgr.getStreamVolume(AudioManager.STREAM_MUSIC));
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate: ");
        if (Build.VERSION.SDK_INT <= 19){
            openSiteToFixCrash();
        }
        deleteCache(ContextGeeter.getAppContext());
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        pv_view = findViewById(R.id.pv_view);
        toolbar = findViewById(R.id.mainToolbar);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null){
            getSupportActionBar().setDisplayShowTitleEnabled(false);
        }
        Button setLanguageButton = findViewById(R.id.set_language);
        setLanguageButton.setText(R.string.set_language);
        playButton = findViewById(R.id.playButton);
        drawerLayout = findViewById(R.id.drawer_layout);
        new ActionBarDrawerToggle(this, drawerLayout,toolbar,
                R.string.navigation_drawer_open,R.string.navigation_drawer_close).syncState();

        navigationView = findViewById(R.id.nav_view);
//        下一行代码作用为使navigation_menu中菜单的图标显示自带的色彩
//        navigationView.setItemIconTintList(null);
        navigationView.setNavigationItemSelectedListener(this);

        updateMenuTitles(navigationView.getMenu().findItem(R.id.nav_stations));


        setBroadcastReceiverStopLivePlayer();

        speaker = findViewById(R.id.speaker);
        music = findViewById(R.id.volumeBar);
        mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

        initVolumeBar(music);
        setVolumeBroadcastReceiver();
        updateLocaleIfNeeded();
//        initPlayer();
        assets = getFileformAssets("BBN_URLs.json");
    }

    private void updateMenuTitles(MenuItem item) {
        String preferenceLanguage = Common.getPreferredLanguageString();
        if ((!preferenceLanguage.equals("English")) && (!preferenceLanguage.equals("Spanish"))
                && (!preferenceLanguage.equals("Portuguese"))){
            item.setTitle(R.string.ways_to_listen);
        } else {
            item.setTitle(R.string.stations);
        }
    }

    public String getFileformAssets(String fileName) {
        String result = "";
        try {
            InputStream inputStream = getResources().getAssets().open(fileName);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int length;
            while ((length = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, length);
            }
            return outputStream.toString(StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            e.printStackTrace();
            return result;
        }
    }

    public void doBind(View view) {
        new AsyncJSONURLsParser(MainActivity.this) {
            @Override
            public void errorMessage(String errorMsg) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), errorMsg, Toast.LENGTH_LONG).show();
                    }
                });
            }

            @Override
            public void processFinish() {

            }

            @Override
            public void receiveData(Object dataObj) {
                String result = (String) dataObj;
                if (result != null) {
                    playLiveStreamWithURL(result);
                }
            }
        }.execute(new String[]{assets, "LiveStreamURLs"});
    }

    public void doUnbind(View view) {
//        stopService(new Intent(this, PlayerService.class));
        stopService(psIntent);
    }

    public void playLiveStreamWithURL(String result) {
        psIntent = new Intent(MainActivity.this, PlayerService.class);
        psIntent.setData(Uri.parse(result));
        psIntent.putExtra("content_type:", 2);
        startService(psIntent);
        bindService(psIntent, mConnection, BIND_IMPORTANT);
    }

    public static void deleteCache(Context appContext) {
        deleteDir(appContext.getCacheDir());
    }

    private static boolean deleteDir(File cacheDir) {
        if ((cacheDir != null) && (cacheDir.isDirectory())) {
            String[] fileNameArray = cacheDir.list();
            for (int i = 0; i < fileNameArray.length; i++) {
                if (!deleteDir(new File(cacheDir, fileNameArray[i]))) {
                    return false;
                }
            }
            return cacheDir.delete();
        }
        if ((cacheDir != null) && (cacheDir.isFile())) {
            return cacheDir.delete();
        }
        return false;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if ((requestCode == LANGUAGE_SETUP_CODE) && (resultCode == LANGUAGE_RESULT_CODE)){
            startActivity(new Intent(this, MainActivity.class));
            finish();
            if (playerServiceIntent != null) {
                playerServiceIntent.destroyPlayer();
                playButton.setImageResource(R.drawable.ic_media_play);
            }
            if (mBounded){
                mBounded = false;
            }
        }
    }

    public void startPlaying(View view) {
        if (mBounded) {
            playButton.setImageResource(R.drawable.ic_media_play);
            mBounded = false;
            doUnbind(view);
            playerServiceIntent.destroyPlayer();
        } else {
            playButton.setImageResource(R.drawable.ic_media_pause);
            doBind(view);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode != KeyEvent.KEYCODE_VOLUME_DOWN) && (keyCode != KeyEvent.KEYCODE_VOLUME_UP)){
            return super.onKeyDown(keyCode, event);
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Message msg = Message.obtain();
                handler.sendEmptyMessage(VOLUME_CHANGED);
            }
        });
//        Intent intent = new Intent();
//        intent.setAction("org.bbnradio.VOLUME_CHANGED_ACTION");
//        ContextGeeter.getAppContext().sendBroadcast(intent);
        return false;
    }

    public void openLanguageSettings(View view) {
        startActivityForResult(new Intent(this, SettingsActivity.class), LANGUAGE_SETUP_CODE);
    }

    public void openBBNWebsite(View view) {
        startActivity(new Intent("android.intent.action.VIEW", Uri.parse("https://bbn1.bbnradio.org")));
    }

    public void openSiteToFixCrash(){
        startActivity(new Intent("android.intent.action.VIEW", Uri.parse("http://bbn1.bbnradio.org/english/android-update/")));
    }

    private void initVolumeBar(SeekBar paramSeekBar) {
        int i = Color.parseColor("#008959");
        int j = Color.parseColor("#003800");
        setVolume(paramSeekBar);
        paramSeekBar.getProgressDrawable().setColorFilter(i, PorterDuff.Mode.SRC_IN);
        if (Build.VERSION.SDK_INT >= 16) {
            paramSeekBar.getThumb().setColorFilter(j, PorterDuff.Mode.SRC_IN);
        }
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        speaker.setImageResource(R.drawable.speaker_66);
        paramSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mgr.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 4);
                if (progress <= 4) {
                    speaker.setImageResource(R.drawable.speaker_0);
                } else if (progress <= 7) {
                    speaker.setImageResource(R.drawable.speaker_33);
                } else if (progress <= 10) {
                    speaker.setImageResource(R.drawable.speaker_66);
                } else if (progress > 11) {
                    speaker.setImageResource(R.drawable.speaker_99);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                setVolumeControlStream(Integer.MIN_VALUE);
            }
        });
    }

    private void setVolume(SeekBar paramSeekBar) {
        paramSeekBar.setMax(mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
        paramSeekBar.setProgress(mgr.getStreamVolume(AudioManager.STREAM_MUSIC));
    }


    public void getLocks() {
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (wifiManager != null) {
            wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "BBN:WiFiLockTag");
            wifiLock.acquire();
        }
        PowerManager powerManager = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        if (powerManager != null) {
            wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BBN:WiFiLockTag");
            wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
        }
    }

    private void verifyBatteryOptimiztionSettings() {
        if (Build.VERSION.SDK_INT >= 23) {
//            int i = getSharedPreferences("MyPreferences",MODE_PRIVATE).getInt("battery",0);
            int i = readSharedPref("battery", 0);
            powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
            packageName = ContextGeeter.getAppContext().getPackageName();
            if (powerManager != null) {
                boolean ignoringBatteryOptimizations = powerManager.isIgnoringBatteryOptimizations(packageName);
                if ((i == 0) && (!ignoringBatteryOptimizations)) {
                    showBatteryOptimizationAlert();
                }
            }
        }
    }

    private void showBatteryOptimizationAlert() {
        android.app.AlertDialog.Builder builderDialog = new AlertDialog.Builder(this);
        builderDialog.setTitle(R.string.Message);
        builderDialog.setMessage(R.string.instructions);
        builderDialog.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (Build.VERSION.SDK_INT >= 23) {
                    Intent intent = new Intent();
//                    intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
                    //需要添加权限android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
                    intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                    intent.setData(Uri.parse("package:" + packageName));
                    startActivity(intent);
                    if (powerManager.isIgnoringBatteryOptimizations(packageName)) {
                        writeSharedPref("battery", 1);

                    }
                }
            }
        }).setNegativeButton(R.string.later, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                writeSharedPref("battery", 0);
            }
        });
        builderDialog.show();
    }

    private void writeSharedPref(String key, int value) {
        sharedPreferences = getSharedPreferences("MyPreferences", MODE_PRIVATE);
        sharedPreferences.edit().putInt(key, value);
        sharedPreferences.edit().apply();
    }

    private int readSharedPref(String key, int defValue) {
        sharedPreferences = getSharedPreferences("MyPreferences", MODE_PRIVATE);
        return sharedPreferences.getInt(key, defValue);
    }

    @Override
    protected void onStart() {
        super.onStart();
        getLocks();
        Log.d(TAG, "onStart: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        verifyBatteryOptimiztionSettings();
        setVolume(music);
        Log.d(TAG, "onResume: ");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(updateUIReceiver);
        unregisterReceiver(updateVolumeSeekbar);
        wakeLock.release();
        wifiLock.release();
        Log.d(TAG, "onDestroy: ");
    }

    @Override
    public void onBackPressed() {
        if (mBounded) {
            unbindService(mConnection);
            mBounded = false;
        }
        stopService(psIntent);
        playerServiceIntent.destroyPlayer();
        super.onBackPressed();
    }

    private void setVolumeBroadcastReceiver(){
        IntentFilter volInFilter = new IntentFilter();
        volInFilter.addAction("org.bbnradio.VOLUME_CHANGED_ACTION");
        updateVolumeSeekbar = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                int keyCode = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
                music.setProgress(keyCode);
            }
        };
        registerReceiver(updateVolumeSeekbar,volInFilter);
    }

    private void setBroadcastReceiverStopLivePlayer() {
        IntentFilter localIntentFilter = new IntentFilter();
        localIntentFilter.addAction("org.bbnradio.stop.live.player");
        updateUIReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                Bundle intentExtras = intent.getExtras();
                if ((context != null) && (intentExtras.getInt("StopLivePlayer") == 5)) {
                    if (playerServiceIntent != null) {
                        playerServiceIntent.destroyPlayer();
                        playButton.setImageResource(R.drawable.ic_media_play);
                    }
                    if (mBounded) {
                        unbindService(mConnection);
                        mBounded = false;
                    }
                }
            }
        };
        registerReceiver(updateUIReceiver,localIntentFilter);
    }

    private void updateLocaleIfNeeded() {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        if (sharedPreferences.contains("lang_setting")) {
            Locale locale = new Locale(sharedPreferences.getString("lang_setting", ""));
            String localeStr = String.valueOf(locale);
            if (!locale.equals(Locale.getDefault())) {
                Resources resources = getResources();
                Configuration configuration = resources.getConfiguration();
                if (localeStr.contains("_")) {
                    configuration.locale = new Locale(localeStr.substring(0, localeStr.indexOf("_")),
                            localeStr.substring(localeStr.indexOf("_") + 1, localeStr.length()).toUpperCase());
                } else {
                    configuration.locale = new Locale(localeStr, "");
                }
                resources.updateConfiguration(configuration, resources.getDisplayMetrics());
                Locale.setDefault(locale);
                RefreshApp.refreshApp(this);
            }
        }
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        return false;
    }
}
